package be.nepherte.movmanager.client.ui.components;

import java.util.ArrayList;
import java.util.List;

import be.nepherte.movmanager.domain.Movie;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * This class implements a movie details view. Only 1 {@link Movie movie} and
 * all its information is displayed at a time.
 * 
 * <p>
 * Copyright © 2010 Bart Verhoeven
 * </p>
 * 
 * <p>
 * This file is part of MovManager.
 * </p>
 * 
 * <p>
 * MovManger is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * </p>
 * 
 * <p>
 * MovManger is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * </p>
 * 
 * <p>
 * You should have received a copy of the GNU General Public License along with
 * MovManger. If not, see http://www.gnu.org/licenses/.
 * </p>
 * 
 * @author	Bart Verhoeven
 * @version	0.1
 */
public class MovieDetailsView extends AbstractMoviesView implements ClickHandler, LoadHandler {
	/**Main panel.*/
	private final VerticalPanel pnlMain = new VerticalPanel();
	/**Movie panel.*/
	private final HorizontalPanel pnlMovie = new HorizontalPanel();
	/**Movie poster.*/
	private final Image poster = new Image();
	/**Movie grid.*/
	private final MovieGrid movieDetails = new MovieGrid(null, false);
	/**A image button place holder for the left arrow to navigate through the movie table list.*/
	private final Image btnPrev = new Image(GWT.getModuleBaseURL() + "images/arrow_blank.png");
	/**A image button place holder for the right arrow to navigate through the movie table list.*/
	private final Image btnNext = new Image(GWT.getModuleBaseURL() + "images/arrow_blank.png");
	
	/**
	 * Creates a new empty movie details view.
	 */
	public MovieDetailsView() {
		this(new ArrayList<Movie>());
	}
	
	/**
	 * Creates a new movie details view. 
	 * 
	 * @param	movies
	 * 			list of movies in this view
	 */
	public MovieDetailsView(List<Movie> movies) {
		super(movies);
		super.maxVisibleEntries = 1;
		btnPrev.addClickHandler(this);
		btnNext.addClickHandler(this);
		poster.addLoadHandler(this);
		initMainPanel();
	}
	
	/**
	 * Initializes the main panel.
	 */
	private void initMainPanel() {
		formatMoviePanel();
		formatMainPanel();
		
		// only set movie when there are movies
		if (movies != null && super.movies.size() != 0) {
			this.setMovies(super.movies);
		}
		initWidget(pnlMain);
	}
	
	/**
	 * Formats the movie panel.
	 */
	private void formatMoviePanel() {
		pnlMovie.setSpacing(10);
		pnlMovie.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
		poster.setWidth("350px");
	}
	
	/**
	 * Formats the main panel.
	 */
	private void formatMainPanel() {
		pnlMain.setSpacing(10);
		pnlMain.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
	}

	@Override
	public void navigateLeft() {
		if (firstMovieIndex == 0)
			return;
		
		displayMovie(firstMovieIndex-1);
		updateNavigationArrows();
	}

	@Override
	public void navigateRight() {
		if (firstMovieIndex == super.movies.size()-1)
			return;
		
		displayMovie(firstMovieIndex+1);
		updateNavigationArrows();
	}

	@Override
	public Image getLeftNavigationElement() {
		return btnPrev;
	}

	@Override
	public Image getRightNavigationElement() {
		return btnNext;
	}

	/**
	 * Ignores i. The capacity of this movie details view is fixed to 1.
	 */
	@Override
	public void setMaxVisibleElements(int i) {
	}

	@Override
	public void setMovies(List<Movie> movies) {
		this.movies = movies;
		displayMovie(0);
	}
	
	@Override
	public void setMovies(List<Movie> movies, int firstMovieIndex) {
		this.movies = movies;
		displayMovie(firstMovieIndex);
	}
	

	/**
	 * Displays the <tt>startIndex>-th movie.
	 * 
	 * @param	startIndex
	 * 			index of the movie to be displayed
	 */
	private void displayMovie(int startIndex) {
		pnlMain.clear();
		if (movies != null && movies.size() != 0) {
			pnlMain.setVisible(false);
			super.firstMovieIndex = startIndex;
			poster.setUrl(!movies.get(startIndex).getMoviePoster().equals("" ) ? movies.get(startIndex).getMoviePoster() : GWT.getModuleBaseURL() + "images/noposter.png");
			pnlMain.add(new HTML("<font size=\"6\"><strong>" + movies.get(startIndex).getTitle() + "</strong></font>"));
			movieDetails.setMovie(movies.get(startIndex));
			pnlMovie.add(poster);
			pnlMovie.add(movieDetails);
			pnlMain.add(pnlMovie);
			updateNavigationArrows();
		}
	}

	/**
	 * Updates the navigation arrows.
	 */
	private void updateNavigationArrows() {
		// update left arrow
		if (firstMovieIndex > 0) {
			btnPrev.setUrl(GWT.getModuleBaseURL() + "images/arrow_left.png");
			btnPrev.setTitle("View result " + (firstMovieIndex) + " of " + movies.size());
		}
		else {
			btnPrev.setUrl(GWT.getModuleBaseURL() + "images/arrow_blank.png");
			btnPrev.setTitle(null);
		}
		
		// update right arrow
		if (firstMovieIndex+maxVisibleEntries < movies.size()) {
			btnNext.setUrl(GWT.getModuleBaseURL() + "images/arrow_right.png");
			btnNext.setTitle("View result " + (firstMovieIndex+2) +  " of " + movies.size());
		}
		else {
			btnNext.setUrl(GWT.getModuleBaseURL() + "images/arrow_blank.png");
			btnNext.setTitle(null);
		}
	}

	/**
	 * Called when a click event is fired by one of the clickable components in
	 * this tab.
	 */
	@Override
	public void onClick(ClickEvent event) {
		//  the left navigation arrow is clicked
		if (event.getSource().equals(btnPrev) && !btnPrev.getUrl().contains("blank")) {
			navigateLeft();
			return;
		}
		
		// the right navigation arrow is clicked
		if (event.getSource().equals(btnNext) && !btnNext.getUrl().contains("blank")) {
			navigateRight();
			return;
		}
	}

	@Override
	public void onLoad(LoadEvent event) {
		if (event.getSource().equals(poster))
			pnlMain.setVisible(true);
	}
}
